package com.san.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzk.pojo.UserBasic;
import com.hzk.vo.CaseUser;
import com.san.mapper.OverdueMapper;
import com.san.mapper.RuleMapper;
import com.san.mapper.SeckillApplicationFormMapper;
import com.san.pojo.Overdue;
import com.san.pojo.Rule;
import com.san.pojo.SeckillApplicationForm;
import com.san.service.IUserBasicService;
import com.san.service.RuleService;
import com.san.vo.RespBean;
import com.san.vo.RespBeanEnum;
import com.san.vo.RuleVo;
import com.san.vo.appVo;
import org.kie.api.KieBase;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class DroolServiceImpl extends ServiceImpl<RuleMapper, Rule> implements RuleService {
    int count = 0;
    @Autowired
    private KieBase kieBase;
    @Autowired
    private SeckillApplicationFormMapper applicationMapper;
    @Autowired
    private SeckillApplicationFormServiceImpl seckillApplicationFormService;
    @Autowired
    private OverdueMapper overdueMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IUserBasicService iUserBasicService;
    @Autowired
    private RuleMapper ruleMapper;

    public RespBean executeRule(@CaseUser UserBasic user, Long goodsid, String token) {

        int count = 0;
        ValueOperations valueOperations = redisTemplate.opsForValue();
        KieSession kieSession = kieBase.newKieSession();
        //以token为k，拿用户的数据user

        if (user == null) {
            return RespBean.error(RespBeanEnum.NULL_USER_ERROR);
        }
        if (redisTemplate.hasKey("application:" + user.getId())) {
            if ((valueOperations.get("application:" + user.getId()).equals("成功"))) {

                String getpath = iUserBasicService.getpath(user, goodsid, token);
                return appVo.success(1, token,getpath);
            } else {
                return RespBean.error(RespBeanEnum.Reappllication_ERROR);
            }
        } else {
            //创建Fact对象，并且赋值
            Long id1 = user.getId();//这一个id号要和user的id号相对应
            /*int count = 0;*/

            Rule rule = (Rule) redisTemplate.opsForValue().get("rule:" + goodsid);
            Integer agelimit = rule.getAgelimit();
            Long moneylimit = rule.getMoneylimit();
            int payofflimit = rule.getPayofflimit();
            Long yearslimit = rule.getYearslimit();
            List<Overdue> list = new LinkedList();
            List<Overdue> overlist = overdueMapper.SeletListById(id1);
            Iterator<Overdue> iterator1 = overlist.iterator();
            while (iterator1.hasNext()) {
                Overdue next = iterator1.next();
                if (new Date().getTime() - next.getLateTime().getTime() <= (yearslimit * 3600000 * 24 * 365)) {
                    list.add(next);
                }
            }

            int size = list.size();
            SeckillApplicationForm application = new SeckillApplicationForm();
            if (size != 0) {
                Iterator<Overdue> iterator = list.iterator();
                while (iterator.hasNext()) {
                    //迭代器获取每一个用户的逾期记录
                    Overdue next = iterator.next();
                    //需要同时满足不是黑名单里面的人，必须有工作
                    if (next.getBlacklist() || !next.getWorkingState()) {//同时为真才为真
                        continue;
                    }
                    RuleVo ruleVo = new RuleVo();
                    ruleVo.setAge(agelimit);
                    ruleVo.setMoney(moneylimit);
                    ruleVo.setPayofftime(payofflimit);
                    ruleVo.setTime(yearslimit);
                    ruleVo.setAge1(next.getAge());
                    ruleVo.setMoney1(next.getOverdueRecord());
                    ruleVo.setPayofftime1(next.getPayOffDate().getTime() - next.getLateTime().getTime());
                    /*ruleVo.setTime1(new Date().getTime() - next.getLateTime().getTime());*/
                    //将数据交给规则引擎，规则引擎会根据提供的数据进行规则匹配
                    kieSession.insert(ruleVo);
                    //执行规则引擎，触发规则
                    kieSession.fireAllRules();
                    System.out.println(ruleVo.getCount());
                    if (ruleVo.getCount() == 1) {
                        count++;
                    }
                }
                //关闭kieSession
                kieSession.dispose();
                if (count == size) {
                    inserts(application, user, valueOperations, "成功");
                    String getpath = iUserBasicService.getpath(user, goodsid, token);
                    return appVo.success(1, token,getpath);

                } else {
                    inserts(application, user, valueOperations, "失败");
                    return RespBean.error(RespBeanEnum.appllication_ERROR);
                }

            }
            inserts(application, user, valueOperations, "成功");
            String getpath = iUserBasicService.getpath(user, goodsid, token);
            return appVo.success(1, token,getpath);

        }

    }

    public void inserts(SeckillApplicationForm application, UserBasic user, ValueOperations valueOperations, String i) {
        try {
            application.setId(user.getId());
            application.setPass(i);
            application.setDate(new Date());
            application.setUsername(user.getUsername());
            applicationMapper.insert(application);
        } catch (Exception exception) {
            if (exception instanceof SQLIntegrityConstraintViolationException) {
                boolean id = seckillApplicationFormService.update(new UpdateWrapper<SeckillApplicationForm>()
                        .eq("id", user.getId()).setSql("seckill_time=" + "seckill_time+1").setSql("pass=" + i));
                valueOperations.decrement("application:" + user.getId());
                /*valueOperations.set("application:" + user.getId(), i);*/
            }
        }
        valueOperations.set("application:" + user.getId(), i, 1, TimeUnit.MINUTES);
    }
}
